package libra.controller;

import java.net.URI;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.http.converter.ByteArrayHttpMessageConverter;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.StringHttpMessageConverter;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.http.converter.support.AllEncompassingFormHttpMessageConverter;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

import libra.MyLB;
import libra.model.JsonResult;
import libra.model.Provider_Pay;

@RestController
@RequestMapping("consumer")
public class ConsumerReqController {
	@Autowired
	RestTemplate restTemplate;
	
	@Value("${server.servlet.context-path}")
	String from;
	
//	String urlPrefix = "http://127.0.0.1:20310/signle_provider_payment_20310";
	String urlPrefix = "http://PROVIDER-PAYMENT/providerPayment";
	
	@RequestMapping("create")
	public Object create( HttpServletRequest req ){
		// 封装参数，千万不要替换为Map与HashMap，否则参数无法传递
        MultiValueMap<String, Object> paramMap = new LinkedMultiValueMap<String, Object>();
        paramMap.add("serial", from + "_@_" + Provider_Pay.genUuid());
		return restTemplate.postForObject(urlPrefix+"/provider/save", paramMap, JsonResult.class);
	}
	
	@RequestMapping("find")
	public Object find( Integer id, HttpServletRequest req ){
		// 封装参数，千万不要替换为Map与HashMap，否则参数无法传递
        MultiValueMap<String, Object> paramMap = new LinkedMultiValueMap<String, Object>();
        paramMap.add("id", id);
		return restTemplate.postForObject(urlPrefix+"/provider/queryOne", paramMap, JsonResult.class);
	}
	@RequestMapping("list")
	public Object list( HttpServletRequest req ){
		// 封装参数，千万不要替换为Map与HashMap，否则参数无法传递
        MultiValueMap<String, Object> paramMap = new LinkedMultiValueMap<String, Object>();
		return restTemplate.postForObject(urlPrefix+"/provider/queryList", paramMap, JsonResult.class);
	}
	
	
	@Autowired
	DiscoveryClient discoveryClient;
	@RequestMapping("DiscoveryClient")
	public Object discoveryClient( HttpServletRequest req ){
		Map<String, Object> result = new HashMap<String, Object>();
		
		// 获取EurekaServer的注册服务列表
		List<String> services = discoveryClient.getServices();
		System.out.println( "discoveryClient.getServices() -> "+services );
		for (String serviceName : services) {
			List<Map<String, Object>> list = new ArrayList<Map<String,Object>>();
			result.put(serviceName, list);
			// 通过注册为服务名称，spring.application.name来进行服务的检索发现
			List<ServiceInstance> srvList = discoveryClient.getInstances(serviceName);
			for( ServiceInstance si : srvList ) {
				Map<String, Object> instance = new HashMap<String, Object>();
				list.add(instance);
				
				instance.put("getServiceId", si.getServiceId());
				instance.put("getHost", si.getHost());
				instance.put("getPort", si.getPort());
				instance.put("getUri", si.getUri());
				instance.put("getInstanceId", si.getInstanceId());
				instance.put("getScheme", si.getScheme());
				instance.put("getMetadata", si.getMetadata());
				System.out.println(instance);
			}
		}
		
		return result;
	}
	
	/**
	 * 使用纯手写自定义负载均衡策略实现。使用该方式时，需要关闭Ribbon相关使用
	 * 如：
	 * 		1、主启动类的@RibbonClient注解需要屏蔽
	 * 		2、restTemplate的@LoadBalanced注解需要屏蔽
	 * 因为有上述条件需要屏蔽，因此本次请求所有的均由方法内不构造
	 */
	static final MyLB myLB = new MyLB();
	@RequestMapping("myLbFind")
	public Object myLbFind( Integer id, HttpServletRequest req ){
        List<ServiceInstance> instances = discoveryClient.getInstances("PROVIDER-PAYMENT");
        if(instances == null || instances.size() <= 0) {
            return null;
        }
        ServiceInstance serviceInstance = myLB.instances(instances);
        URI uri = serviceInstance.getUri();
		
		
		// 封装参数，千万不要替换为Map与HashMap，否则参数无法传递
        MultiValueMap<String, Object> paramMap = new LinkedMultiValueMap<String, Object>();
        paramMap.add("id", id);
        
		RestTemplate rest = new RestTemplate();
		List<HttpMessageConverter<?>> list = new ArrayList<HttpMessageConverter<?>>();
		list.add(new StringHttpMessageConverter(Charset.forName("UTF-8")));
		list.add(new ByteArrayHttpMessageConverter());
		list.add(new AllEncompassingFormHttpMessageConverter());
		list.add(new MappingJackson2HttpMessageConverter());
		rest.setMessageConverters(list);
		
		return rest.postForObject(uri + "/providerPayment" +"/provider/queryOne", paramMap, JsonResult.class);
	}
}
